home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / mint / mint095s.zoo / src / asm / context.s next >
Encoding:
Text File  |  1992-06-14  |  6.6 KB  |  190 lines

  1. ;
  2. ; routines for saving/restoring user contexts
  3. ;
  4. ; long build_context(struct context *sav):
  5. ;    Called from an interrupt handler (such as the trap #1 routine
  6. ;    for system calls) saves the context of the interrupted
  7. ;    routine. Assumes that no user registers have been changed
  8. ;    since the interrupt, and that the PC and status register
  9. ;    are still on the stack. Returns the stack pointer being used
  10. ;    at the time of the interrupt **in register a1**.
  11. ;
  12. ; long save_context(struct context *sav):
  13. ;    Saves the context of the calling routine in the area pointed
  14. ;    to by sav. Save_context always returns 0 when initially called;
  15. ;    this is so processes can (by suitably manipulating the
  16. ;    saved registers) tell when the return from save_context is
  17. ;    actually caused by restoring the context, e.g.:
  18. ;        if (save_context(sav) == 0) {        <<-- L1
  19. ;            /* do some stuff */
  20. ;            sav.regs[D0] = 1;    /* for restore context */
  21. ;            restore_context(sav);    /* goes back to L1 */
  22. ;        }
  23. ;        else /* this is the second time through */
  24. ;
  25. ; void restore_context(struct context *sav):
  26. ;    Restores a context previously saved by build_context or save_context.
  27. ;    Since the program counter is part of the context, this function
  28. ;    will never return (it's like longjmp()).
  29. ;
  30. ; $Log: context.s,v $
  31. ; Revision 1.6  1992/03/31  14:02:08  AGK
  32. ; Fixed for real Motorola syntax (many thanks to ERS for keeping these
  33. ; files in step with the GAS ones).
  34. ;
  35. ; Revision 1.5  1992/03/31  13:55:28  AGK
  36. ; Checked in MiNT 0.93 sources
  37. ;
  38. ; Revision 1.4  1991/05/31  15:55:00  AGK
  39. ; Tested only a byte in the save frame, not a word (my mistake). Bumped FPU
  40. ; frame size up to 216 bytes, the 68882 manual is wrong (thanks Motorola!)
  41. ;
  42. ; Revision 1.3  1991/05/31  09:58:44  AGK
  43. ; Fixed stack frame format manipulation so we use d1, not d0, which is
  44. ; needed later for super/user mode determination.
  45. ;
  46. ; Revision 1.2  1991/05/31  09:48:06  AGK
  47. ; Changes to accomodate longer stack frames etc.
  48. ;
  49. ; Revision 1.1  1991/05/30  17:22:02  AGK
  50. ; Initial revision
  51. ;
  52.     SECTION    TEXT
  53.     
  54.     XDEF    _build_context
  55.     XDEF     _save_context
  56.     XDEF    _restore_context
  57.     XREF    _fpu
  58.     XREF    _m68010
  59.     
  60. _build_context:
  61.     move.l    a0,-(sp)    ; save a0; we'll use it for scratch
  62.     move.l    8(sp),a0    ; get address of save area
  63.  
  64. ; if running with a true coprocessor we need to save the FPU state
  65.  
  66.     tst.w    _fpu        ; is there a true FPU in the system
  67.     beq.s    nofpu
  68.     fsave    78(a0)        ; save internal state frame
  69.     tst.b    78(a0)        ; if NULL frame then the FPU is not in use
  70.     beq.s    nofpu        ; skip programmer's model save
  71.     fmovem.x    fp0-fp7,294(a0)        ; save data registers
  72.     fmovem.l    fpcr/fpsr/fpiar,390(a0)    ; and control registers
  73. nofpu:
  74.     movem.l    d0-d7/a0-a6,(a0)    ; save registers D0-D7/A0-A6
  75.     move.l    14(sp),66(a0)    ; save PC of context
  76.     move.w    12(sp),d0    ; get SR of context
  77.     move.w    d0,64(a0)    ; save it 
  78.     tst.w    ($59e).w    ; test longframe (AKP)
  79.     beq.s    short1        ; short
  80.     lea    20(sp),a1    ; else long
  81.     
  82.     move.w    18(sp),d1    ; fetch frame format word
  83.     move.w    d1,402(a0)    ; and stash it away for later
  84.     tst.w    _m68010        ; are we on a 68010?
  85.     bne.s    short2        ; yes -- so it's a simple interrupt frame
  86. ; note: in order to have got to this point in the code we must be
  87. ; running on an 020/030 hence we can use the extra processor instructions
  88.     bftst    d1{16:4}    ; is it the simple interrupt frame ?
  89.     beq.s    short2        ; yes so just dump the stack contents
  90.     movem.l    (a1)+,d1-d3    ; instruction address/4 internal words
  91.     movem.l    d1-d3,404(a0)
  92.     bra.s    short2
  93. short1:
  94.     lea    18(sp),a1    ; save supervisor stack pointer
  95. short2:                ; note that it should be pointing above the PC
  96.     move.l    a1,70(a0)
  97.     move.l    usp,a1        ; save user stack pointer
  98.     move.l    a1,60(a0)
  99.     btst    #13,d0        ; check for supervisor mode
  100.     beq.s    L_CONT1        ; user mode; we already have stack in a1
  101. L_SUPER1:
  102. ; note: this was lea a0@(18), but moving from the save state buffer 
  103. ; means not testing longframe again. (AKP)
  104.     move.l    70(a0),a1    ; was using super stack pointer before interrupt
  105.                 ; 
  106. L_CONT1:
  107.     move.l    ($408).w,74(a0)    ; save GEMDOS terminate vector
  108.     move.l    (sp)+,32(a0)    ; save old register a0
  109.     rts
  110.  
  111. _save_context:
  112.     move.l    a0,-(sp)    ; save a0
  113.     move.l    8(sp),a0    ; get address of context save area
  114.  
  115. ; if running with a true coprocessor we need to save the FPU state
  116.  
  117.     tst.w    _fpu        ; is there a true FPU in the system
  118.     beq.s    nofpu2
  119.     fsave    78(a0)        ; save internal state frame
  120.     tst.b    78(a0)        ; if NULL frame then the FPU is not in use
  121.     beq.s    nofpu2        ; skip programmer's model save
  122.     fmovem.x    fp0-fp7,294(a0)        ; save data registers
  123.     fmovem.l    fpcr/fpsr/fpiar,390(a0)    ; and control registers
  124. nofpu2:
  125. ; note: I am somewhat unsure of this assumption, viz that save_context
  126. ; can never be called in a situation where a co-processor
  127. ; mid-instruction stack frame would be required. I suspect this is a
  128. ; valid assumption, in which case the above FPU code is redundant, the
  129. ; next line is not however!
  130.  
  131.     clr.w    402(a0)        ; mark as a 4 word stack frame
  132.  
  133.     movem.l    d0-d7/a0-a6,(a0)    ; save D0-D7/A0-A6
  134.     lea    8(sp),a1
  135.     move.l    a1,70(a0)    ; save supervisor stack pointer
  136.                 ; note that it should be pointing above the PC
  137.     move.l    -4(a1),66(a0)    ; save PC
  138.     move.l    usp,a1
  139.     move.l    a1,60(a0)    ; save user stack pointer
  140.     move.w    sr,d0
  141.     move.w    d0,64(a0)    ; save status register
  142.     move.l    ($408).w,74(a0)    ; save GEMDOS terminate vector
  143.     move.l    (sp)+,32(a0)    ; save old a0
  144.     moveq.l    #0,d0        ; return 0
  145.     rts
  146.  
  147. _restore_context:
  148.     ori.w    #$0700,sr    ; mask interrupts
  149.     move.l    4(sp),a0    ; address of context save area
  150.     move.l    70(a0),sp    ; supervisor stack pointer
  151.     move.l    60(a0),a1
  152.     move.l    a1,usp        ; set user stack pointer
  153.     move.l    74(a0),($408).w    ; restore GEMDOS terminate vector
  154.  
  155.     tst.w    ($59e).w    ; test longframe (AKP)
  156.     beq.s    short3
  157.  
  158.     move.w    402(a0),d0    ; fetch frame format word
  159.     tst.w    _m68010
  160.     bne.s    just0
  161.  
  162. ; again, we reach here only on an 020/030
  163.  
  164.     bftst    d0{16:4}    ; is it the simple interrupt frame ?
  165.     beq.s    just0        ; yes so just push a zero
  166.     movem.l    404(a0),d1-d3    ; saved instruction address/4 internal words
  167.     movem.l    d1-d3,-(sp)
  168. just0:    move.w    d0,-(sp)
  169.     
  170. short3:
  171.     move.l    66(a0),-(sp)    ; push the PC
  172.     move.w    64(a0),d0    ; get status register
  173.     move.w    d0,-(sp)    ; push the status register
  174.  
  175. ; if running with a true coprocessor we need to restore the FPU state
  176.  
  177.     tst.w    _fpu        ; is there a true FPU in the system
  178.     beq.s    nofpu3
  179.     tst.b    78(a0)        ; if NULL frame then the FPU is not in use
  180.     beq.s    short7        ; skip programmer's model restore
  181.     fmovem.l    390(a0),fpcr/fpsr/fpiar    ; restore control registers
  182.     fmovem.x    294(a0),fp0-fp7        ; and data registers
  183. short7:    frestore    78(a0)            ; finally the internal state
  184.  
  185. nofpu3:
  186.     movem.l    (a0),d0-d7/a0-a6 ; restore registers d0-d7/a0-a6
  187.     rte            ; jump back to old context
  188.  
  189.     END
  190.